package com.skivingcloud.report.ureport.controller;

import com.bstek.ureport.export.ExportConfigure;
import com.bstek.ureport.export.ExportConfigureImpl;
import com.bstek.ureport.export.ExportManager;
import com.bstek.ureport.export.html.HtmlReport;
import com.itextpdf.text.pdf.PdfReader;
import com.skivingcloud.admin.sys.entity.User;
import com.skivingcloud.admin.utils.UserUtil;
import com.skivingcloud.common.exception.BusinessException;
import com.skivingcloud.common.utils.DateUtils;
import com.skivingcloud.common.utils.StringUtils;
import com.skivingcloud.report.ureport.PDFAndOfficeWatermark;

import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;
import java.util.Map;

/**
 * UReport2后端导出报表
 */
@RestController
@RequestMapping("/ureportc/export")
public class ExportManagerController {
	
	private static Logger log = LoggerFactory.getLogger(ExportManagerController.class);
	
    @Autowired
    private ExportManager exportManager;

    /**
     * 导出Html报表
     * @param parameters 参数
     * @return 返回一个HtmlReport对象，里面有报表产生的HTML及相关CSS
     */
    @GetMapping("/exportHtml")
    public HtmlReport exportHtml(@RequestParam Map<String, Object> parameters, HttpServletRequest request){
        if(!parameters.containsKey("file")){
            throw new BusinessException("必须传入文件名");
        }
        String file = parameters.get("file").toString();
        return exportManager.exportHtml(file, request.getContextPath(), parameters);
    }

    /**
     * 导出指定页码的Html报表
     * @param parameters 参数
     * @param pageIndex 页码
     * @return 返回一个HtmlReport对象，里面有报表产生的HTML及相关CSS
     */
    @GetMapping("/exportHtmlPage")
    public HtmlReport exportHtmlPage(@RequestParam Map<String, Object> parameters, @RequestParam int pageIndex, HttpServletRequest request){
        if(!parameters.containsKey("file")){
            throw new BusinessException("必须传入文件名");
        }
        String file = parameters.get("file").toString();
        return exportManager.exportHtml(file, request.getContextPath(), parameters, pageIndex);
    }

    /**
     * 导出带水印的pdf文件，在线打开方式
     * @param parameters 参数{file:报表文件名,password:加密密码没有时默认不加密,waterText:水印内容不传时默认（姓名+员工编号+日期时间,如果取不到登录用户则水印为“中石油企业年金管理信息系统”）,.....}
     * @param request
     * @param response
     */
    @GetMapping("/exportPdf")
    public void exportPdf(@RequestParam Map<String, Object> parameters, HttpServletRequest request, HttpServletResponse response){
        try {
            User user = UserUtil.getUser();
            if(!parameters.containsKey("file")){
                throw new BusinessException("必须传入文件名");
            }
            String file = parameters.get("file").toString();
            String password = parameters.get("password") == null ? null : parameters.get("password").toString();
            String waterText = parameters.get("waterText") == null ? null : parameters.get("waterText").toString();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ExportConfigure config = new ExportConfigureImpl(file, parameters, out);
            exportManager.exportPdf(config);
            PDDocument pdDocument = Loader.loadPDF(out.toByteArray());
            PDFRenderer renderer = new PDFRenderer(pdDocument);
            PdfReader reader = new PdfReader(out.toByteArray());
            response.setContentType("application/pdf;charset=UTF-8");
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition", "inline;filename=" + java.net.URLEncoder.encode(file.substring(0,file.lastIndexOf(".")) + ".pdf", "UTF-8"));//.zip
            if(waterText == null){
                waterText = user == null ? "中石油企业年金管理信息系统" : user.getStaffName() + user.getStaffId() + " " + DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
            }
            if(StringUtils.isNotBlank(password)){
                PDFAndOfficeWatermark.watermark(reader, waterText, response.getOutputStream(), true, password);
                //图片形式
//                PDFAndOfficeWatermark.orderPdfToImg(pdDocument, waterText, response.getOutputStream());
            }else{
                PDFAndOfficeWatermark.watermark(reader, waterText, response.getOutputStream(), false, null);
                //图片形式
//                PDFAndOfficeWatermark.orderPdfToImg(pdDocument, waterText, response.getOutputStream());
            }
        } catch (Exception e) {
            log.error("导出报表失败", e);
        }
    }

    /**
     * 导出带水印的pdf文件，直接下载方式
     * @param parameters 参数{file:报表文件名,password:加密密码没有时默认不加密,waterText:水印内容不传时默认（姓名+员工编号+日期时间,如果取不到登录用户则水印为“中石油企业年金管理信息系统”）,.....}
     * @param request
     * @param response
     */
    @GetMapping("/exportPdfAttachment")
    public void exportPdfAttachment(@RequestParam Map<String, Object> parameters, HttpServletRequest request, HttpServletResponse response){
        try {
            User user = UserUtil.getUser();
            if(!parameters.containsKey("file")){
                throw new BusinessException("必须传入文件名");
            }
            String file = parameters.get("file").toString();
            String password = parameters.get("password") == null ? null : parameters.get("password").toString();
            String waterText = parameters.get("waterText") == null ? null : parameters.get("waterText").toString();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ExportConfigure config = new ExportConfigureImpl(file, parameters, out);
            exportManager.exportPdf(config);
            PdfReader reader = new PdfReader(out.toByteArray());
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(file.substring(0,file.lastIndexOf(".")) + ".pdf", "UTF-8"));//.zip
            if(waterText == null){
                waterText = user == null ? "中石油企业年金管理信息系统" : user.getStaffName() + user.getStaffId() + " " + DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
            }
            if(StringUtils.isNotBlank(password)){
                PDFAndOfficeWatermark.watermark(reader, waterText, response.getOutputStream(), true, password);
            }else{
                PDFAndOfficeWatermark.watermark(reader, waterText, response.getOutputStream(), false, null);
            }
        } catch (Exception e) {
            log.error("导出报表失败", e);
        }
    }

    /**
     * 不分页导出Excel
     * @param parameters parameters 参数{file:报表文件名,password:加密密码，没有时默认不加密,.....}
     * @param request
     * @param response
     */
    @GetMapping("/exportExcel")
    public void exportExcel(@RequestParam Map<String, Object> parameters, HttpServletRequest request, HttpServletResponse response){
        try {
            User user = UserUtil.getUser();
            if(!parameters.containsKey("file")){
                throw new BusinessException("必须传入文件名");
            }
            String file = parameters.get("file").toString();
            String password = parameters.get("password") == null ? null : parameters.get("password").toString();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ExportConfigure config = new ExportConfigureImpl(file, parameters, out);
            exportManager.exportExcel(config);
            InputStream inputStream = new ByteArrayInputStream(out.toByteArray());
            String excelName = file.substring(0,file.lastIndexOf(".")) + ".xlsx";
            Workbook workbook = com.skivingcloud.common.utils.ExcelUtil.getWorkbook(excelName, inputStream);
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(excelName, "UTF-8"));//.zip
            if(StringUtils.isNotBlank(password)){
                for(int i = 0; i < workbook.getNumberOfSheets(); i++){
                    workbook.getSheetAt(i).protectSheet(password);
                }
            }
            workbook.write(response.getOutputStream());
        } catch (Exception e) {
            log.error("导出报表失败", e);
        }
    }

    public void exportWord(@RequestParam Map<String, Object> parameters, HttpServletRequest request, HttpServletResponse response){
        try {
            if(!parameters.containsKey("file")){
                throw new BusinessException("必须传入文件名");
            }
            String file = parameters.get("file").toString();
            String password = parameters.get("password") == null ? null : parameters.get("password").toString();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ExportConfigure config = new ExportConfigureImpl(file, parameters, out);
            exportManager.exportWord(config);
            InputStream inputStream = new ByteArrayInputStream(out.toByteArray());
            String excelName = file.substring(0,file.lastIndexOf(".")) + ".docx";
            XWPFDocument document = new XWPFDocument(inputStream);
            if(StringUtils.isNotBlank(password)){
                document.enforceCommentsProtection(password, HashAlgorithm.sha512);
            }
            document.write(response.getOutputStream());
        } catch (IOException e) {
            log.error("导出报表失败", e);
        }
    }
}
